//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
// 

#include "tractorDecider.h"

bool tractorDecider::checkFree() {
    if (currentSignal.first == 0)
        return true;
    else
        return false;
}

simtime_t tractorDecider::processNewSignal(AirFrame* frame) {
    EV<< "Processing new signal." << endl;
    if(!checkFree()) {
        currentSignal.first = 0;
        setChannelIdleStatus(true);
        interferences++;
        EV << "We are already trying to receive a signal, so this is noise." << endl;
        return notAgain;
    } else {
        currentSignal.first = frame;
        currentSignal.second = EXPECT_HEADER;
        setChannelIdleStatus(false);
        Signal& signal = frame->getSignal();
        return signal.getReceptionStart() + 0.10 * signal.getDuration();
    }

}

simtime_t tractorDecider::processSignalHeader(AirFrame* frame) {
    Signal& signal = frame->getSignal();
    simtime_t start = signal.getSendingStart();
    EV << "Process Header" << endl;
    frame->setState(EXPECT_END);
    currentSignal.second = EXPECT_END;
    return signal.getReceptionEnd();
}

simtime_t tractorDecider::processSignalEnd(AirFrame* frame) {
    EV<< "Processing end of signal." << endl;
    Signal& signal = frame->getSignal();
    simtime_t start = signal.getSendingStart();

    //--
    int sId = getIdFromName(signal.getSendingModule()->getOwner()->getOwner()->getFullName());
    int rId = getIdFromName(signal.getReceptionModule()->getOwner()->getOwner()->getFullName());
    simtime_t stime = signal.getSendingEnd();
    EV << "CALL READER at sender:" << sId << " receiver:" << rId << " time:" << stime << endl;
    int codeReader = traceReader->searchInTraces(sId, rId, stime);
    checkCodeTraceReader(codeReader, frame);
    //--

    return notAgain;
}

int tractorDecider::getIdFromName(const char* name) {
    std::string strName = name;
    int start = strName.find("[", 0) + 1;
    int end = strName.find("]", 0);
    std::string strID = strName.substr(start, end - start);
    return atoi(strID.c_str());
}

void tractorDecider::checkCodeTraceReader(int code, AirFrame* frame) {
    if (code == 1) {
        foundMessages++;
        EV<< "FOUND MESSAGE!!!!!!!!!";
        phy->sendUp(frame, new DeciderResult(true));
    } else {
        notFoundMessages++;
        EV << "Message not found.";
    }
}

void tractorDecider::convertFileList(const char* fList) {
    string word;
    stringstream stream(fList);
    while (getline(stream, word, ';')) {
        fileList.push_back(word);
    }
}

void tractorDecider::convertFileIds(const char* idFList) {
    string word;
    stringstream stream(idFList);
    while (getline(stream, word, ';')) {
        idFileList.push_back(atoi(word.c_str()));
    }
}

void tractorDecider::finish(){
    EV << "Node: " << this->myIndex << "\nFound messages: " << foundMessages << "\nNot found messages: " << notFoundMessages << "\nInterferences: " << interferences << "\n" << endl;
}
